package com.qzh.QLanguage.ElementAnalyse;

import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 词法解析器（支持转义字符和嵌套字符串检测）
 */
class QLexer {
    private static final Pattern TOKEN_PATTERN = Pattern.compile(
        "(?<STRING>\"(?:\\\\\"|[^\"])*?\")|" +  // 字符串（支持转义）
        "(?<KEYWORLD>[a-zA-Z_][a-zA-Z0-9_]*)|" +      // 标识符
        "(?<LPAREN>\\()|" +
        "(?<RPAREN>\\))|" +
        "(?<SEMICOLON>;)|" +
        "(?<WHITESPACE>\\s+)"
    );

    private final String input;
    private int line = 1;

    public QLexer(String input) {
        this.input = input;
    }

    public List<Token> tokenize() throws SyntaxException {
        List<Token> tokens = new ArrayList<>();
        Matcher matcher = TOKEN_PATTERN.matcher(input);
        int lastEnd = 0;

        while (matcher.find()) {
            // 处理未匹配的字符
            if (matcher.start() > lastEnd) {
                throw new SyntaxException("无法识别的字符: " + input.substring(lastEnd, matcher.start()));
            }

            // 处理各匹配组
            if (matcher.group("STRING") != null) {
                String value = matcher.group().substring(1, matcher.group().length()-1)
                                  .replace("\\\"", "\""); // 处理转义
                tokens.add(new Token(TokenType.STRING, value, line));
            } else if (matcher.group("KEYWORLD") != null) {
                String keyWord = matcher.group();
                tokens.add(keyWord.equals("print") ?
                    new Token(TokenType.KEYWORD, keyWord, line) :
                    new Token(TokenType.IDENTIFIER, keyWord, line));
            } else if (matcher.group("LPAREN") != null) {
                tokens.add(new Token(TokenType.LPAREN, "(", line));
            } else if (matcher.group("RPAREN") != null) {
                tokens.add(new Token(TokenType.RPAREN, ")", line));
            } else if (matcher.group("SEMICOLON") != null) {
                tokens.add(new Token(TokenType.SEMICOLON, ";", line));
            }

            // 处理换行计数
            String whitespace = matcher.group("WHITESPACE");
            if (whitespace != null) {
                line += (int)whitespace.chars().filter(c -> c == '\n').count();
            }

            lastEnd = matcher.end();
        }
        // 添加EOF标记
        tokens.add(new Token(TokenType.EOF, "", line));
        return tokens;
    }
}